/**
 * Copyright 2006 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy 
 * of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0 
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations 
 * under the License.
 */

package com.google.appsforyourdomain.provisioning;

import org.jdom.Document;

import java.util.List;

/**
 * The Account class represents a user account of a hosted domain.
 * This class contains static methods to generate all the XML requests
 * pertaining to an Account.
 * 
 * Sample usage of this class can be found in ProvisioningClient.java
 */
public class Account {

  /**
   * AccountStatus represents the two possible states of a 
   * user account.
   */
  public enum AccountStatus {
    locked, unlocked
  }
  
  // Various REST response XPATH
  protected static final String FIRSTNAME_PATH = 
      "/hs:rest/hs:RetrievalSection/hs:firstName";
  protected static final String LASTNAME_PATH = 
      "/hs:rest/hs:RetrievalSection/hs:lastName";
  protected static final String USERNAME_PATH = 
      "/hs:rest/hs:RetrievalSection/hs:userName";
  protected static final String PASSWORD_PATH = 
      "/hs:rest/hs:RetrievalSection/hs:password";
  protected static final String ACCOUNTSTATUS_PATH = 
      "/hs:rest/hs:RetrievalSection/hs:accountStatus";
  protected static final String ALIAS_PATH = 
      "/hs:rest/hs:RetrievalSection/hs:aliases/hs:alias";
  protected static final String EMAILLIST_PATH = 
      "/hs:rest/hs:RetrievalSection/hs:emailLists/hs:emailList";
  
  protected String firstName;
  protected String lastName;
  protected String userName;
  protected String password;
  protected List<String> aliases;
  protected List<String> emailLists;
  protected AccountStatus accountStatus;
  
  /**
   * Constructs an Account with values
   * 
   * @param firstName firstname of the user
   * @param lastName lastname of the user
   * @param userName username of the user
   * @param password password of the user
   * @param aliases email aliases of the user
   * @param accountStatus status of the account (locked or unlocked)
   */
  public Account(String firstName, String lastName, String userName, 
      String password, List<String> aliases, List<String> emailLists,
      AccountStatus accountStatus) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.userName = userName;
    this.password = password;
    this.aliases = aliases;
    this.emailLists = emailLists;
    this.accountStatus = accountStatus;
  }
    
  public String getFirstName() {
    return firstName;
  }
    
  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }
    
  public String getLastName() {
    return lastName;
  }
    
  public void setLastName(String lastName) {
    this.lastName = lastName;
  }
    
  public String getUserName() {
    return userName;
  }
    
  public void setUserName(String userName) {
    this.userName = userName;
  }
    
  public String getPassword() {
    return password;
  }
    
  public void setPassword(String password) {
    this.password = password;
  }
    
  public List<String> getAliases() {
    return aliases;
  }
    
  public void setAliases(List<String> aliases) {
    this.aliases = aliases;
  }
  
  public List<String> getEmailLists() {
    return emailLists;
  }
  
  public void setEmailLists(List<String> emailLists) {
    this.emailLists = emailLists;
  }

  public AccountStatus getAccountStatus() {
    return accountStatus;
  }
    
  public void setAccountStatus(AccountStatus status) {
    this.accountStatus = status;
  }
  
  /**
   * Creates an Account object using a JDOM document
   * 
   * @param doc JDOM document
   */
  protected static Account createAccountFromXmlDocument(Document doc)
      throws AppsForYourDomainException {
    try {    
      String firstName = AppsUtil.parseXml(doc, FIRSTNAME_PATH);
      String lastName = AppsUtil.parseXml(doc, LASTNAME_PATH);
      String userName = AppsUtil.parseXml(doc, USERNAME_PATH);
      String password = AppsUtil.parseXml(doc, PASSWORD_PATH);
      List<String> aliases = AppsUtil.parseXmlMultipleNodes(doc, ALIAS_PATH);
      List<String> emailLists = AppsUtil.parseXmlMultipleNodes(
        doc, EMAILLIST_PATH);
      String temp = AppsUtil.parseXml(doc, ACCOUNTSTATUS_PATH);
      AccountStatus accountStatus = null;
      if (temp != null && temp.equalsIgnoreCase("locked")) {
        accountStatus = AccountStatus.locked;
      } else if (temp != null && temp.equalsIgnoreCase("unlocked")) {
        accountStatus = AccountStatus.unlocked;
      }
      return new Account(firstName, lastName, userName, password, 
        aliases, emailLists, accountStatus);
    } catch (ParseException e) {
      throw e;
    }
  }
  /**
   * Generates the create account request 
   * 
   * @param firstName firstname of the user
   * @param lastName fastname of the user
   * @param password password of the user
   * @param userName username of the user
   * @param quota email quota (valid only for domains with custom quota). 
   *        Set quota to 0 for default quota
   * @param domainName domain name of the account
   * @param authToken authentication token
   */ 
  protected static String generateCreateAccountRequest(String firstName,
      String lastName, String password, String userName, int quota, 
      String domainName, String authToken) {
    StringBuffer buffer = new StringBuffer(
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    buffer.append(
        "<hs:rest xmlns:hs=\"google:accounts:rest:protocol\" " 
	+ "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
    buffer.append("<hs:type>Account</hs:type>");
    buffer.append("<hs:token>" + authToken + "</hs:token>");
    buffer.append("<hs:domain>" + domainName + "</hs:domain>");
    buffer.append("<hs:CreateSection>");
    buffer.append("<hs:firstName>" + firstName + "</hs:firstName>");
    buffer.append("<hs:lastName>" + lastName + "</hs:lastName>");
    buffer.append("<hs:password>" + password + "</hs:password>");
    buffer.append("<hs:userName>" + userName + "</hs:userName>");
    if (quota != 0){
      buffer.append("<hs:quota>" + quota + "</hs:quota>");
    }
    buffer.append("</hs:CreateSection>");
    buffer.append("</hs:rest>");
    return buffer.toString();
  }
 
  /**
   * Generates the update account request
   * 
   * @param firstName firstname of the user
   * @param lastName lastname of the user
   * @param password password of the user
   * @param userName username of the user
   * @param domainName domain name of the account
   * @param authToken authentication token 
   */ 
  protected static String generateUpdateAccountRequest(String firstName,
      String lastName, String password, String userName, String domainName, 
      String authToken) {
    StringBuffer buffer = new StringBuffer(
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    buffer.append(
        "<hs:rest xmlns:hs=\"google:accounts:rest:protocol\" " 
	+ "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
    buffer.append("<hs:type>Account</hs:type>");
    buffer.append("<hs:token>" + authToken + "</hs:token>");
    buffer.append("<hs:domain>" + domainName + "</hs:domain>");
    buffer.append("<hs:queryKey>userName</hs:queryKey>");
    buffer.append("<hs:queryData>" + userName + "</hs:queryData>");
    buffer.append("<hs:UpdateSection>");
    buffer.append("<hs:firstName>" + firstName + "</hs:firstName>");
    buffer.append("<hs:lastName>" + lastName + "</hs:lastName>");
    buffer.append("<hs:password>" + password + "</hs:password>");
    buffer.append("<hs:userName>" + userName + "</hs:userName>");
    buffer.append("</hs:UpdateSection>");
    buffer.append("</hs:rest>");
    return buffer.toString();
  }
  
  /**
   * Generates a general account request. This request can be used
   * to do a retrieve account or a delete account operation
   *  
   * @param userName username of the user
   * @param domainName domain name of the account
   * @param authToken authentication token
   */ 
  protected static String generateAccountRequest(String userName,
      String domainName, String authToken) {
    StringBuffer buffer = new StringBuffer(
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    buffer.append(
        "<hs:rest xmlns:hs=\"google:accounts:rest:protocol\" " 
	+ "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
    buffer.append("<hs:type>Account</hs:type>");
    buffer.append("<hs:token>" + authToken + "</hs:token>");
    buffer.append("<hs:domain>" + domainName + "</hs:domain>");
    buffer.append("<hs:queryKey>userName</hs:queryKey>");
    buffer.append("<hs:queryData>" + userName + "</hs:queryData>");
    buffer.append("</hs:rest>");
    return buffer.toString();
  }
  
  /**
   * Generates the update account status request 
   * 
   * @param userName username of the user
   * @param status status of the account (locked or unlocked)
   * @param domainName domain name of the account
   * @param authToken authentication token
   */ 
  protected static String generateUpdateAccountStatusRequest(String userName,
      AccountStatus status, String domainName, String authToken) {
    StringBuffer buffer = new StringBuffer(
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    buffer.append(
        "<hs:rest xmlns:hs=\"google:accounts:rest:protocol\" " 
	+ "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">");
    buffer.append("<hs:type>Account</hs:type>");
    buffer.append("<hs:token>" + authToken + "</hs:token>");
    buffer.append("<hs:domain>" + domainName + "</hs:domain>");
    buffer.append("<hs:queryKey>userName</hs:queryKey>");
    buffer.append("<hs:queryData>" + userName + "</hs:queryData>");
    buffer.append("<hs:UpdateSection>");
    buffer.append("<hs:accountStatus>" + status + "</hs:accountStatus>");
    buffer.append("</hs:UpdateSection>");
    buffer.append("</hs:rest>");
    return buffer.toString();
  }
}
